package com.omronble.bp_broadcast.activity;

import android.Manifest;
import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.widget.AppCompatSeekBar;
import androidx.appcompat.widget.Toolbar;

import androidx.core.content.ContextCompat;
import io.reactivex.Observable;

import com.huawei.hmf.tasks.Task;
import com.huawei.hms.common.ApiException;
import com.huawei.hms.common.ResolvableApiException;
import com.huawei.hms.location.FusedLocationProviderClient;
import com.huawei.hms.location.LocationAvailability;
import com.huawei.hms.location.LocationCallback;
import com.huawei.hms.location.LocationRequest;
import com.huawei.hms.location.LocationResult;
import com.huawei.hms.location.LocationServices;
import com.huawei.hms.location.LocationSettingsRequest;
import com.huawei.hms.location.LocationSettingsResponse;
import com.huawei.hms.location.LocationSettingsStatusCodes;
import com.huawei.hms.location.SettingsClient;
import com.iflytek.cloud.SpeechConstant;
import com.omron.lib.OMRONLib;
import com.omron.lib.common.OMRONBLEErrMsg;
import com.omron.lib.device.DeviceType;
import com.omron.lib.model.BPData;
import com.omronble.bp_broadcast.tools.Constants;
import com.omronble.bp_broadcast.R;
import com.omronble.bp_broadcast.tools.DeviceMethod;
import com.omronble.bp_broadcast.tools.Utils;
import com.omronble.bp_broadcast.XService;
import com.omronble.bp_broadcast.bean.TLBean;
import com.omronble.bp_broadcast.fragment.BlueToothFragment;
import com.omronble.bp_broadcast.fragment.SysFragment;
import com.tbruyelle.rxpermissions2.RxPermissions;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.text.SimpleDateFormat;
import java.util.List;


public class MainActivity extends BaseActivity implements View.OnClickListener {

    private String TAG = MainActivity.this.getClass().getSimpleName();
    private SharedPreferences mSharedPreferences;
    private AppCompatSeekBar acSeekBar;
    private Button wifi_fun, dev_fun, bt_fun, sys_info_fun;
    private TextView tvNewest;
    private ImageView imageVoice;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        StatusBarUtil.setColor(this, Color.BLACK);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        initPermission();
        acSeekBar = findViewById(R.id.acSeekBar);
        wifi_fun = findViewById(R.id.wifi_fun);
        dev_fun = findViewById(R.id.dev_fun);
        bt_fun = findViewById(R.id.bt_fun);
        sys_info_fun = findViewById(R.id.sys_info_fun);
        imageVoice = findViewById(R.id.imageVoice);
        tvNewest = findViewById(R.id.tvNewest);
        wifi_fun.setOnClickListener(this);
        dev_fun.setOnClickListener(this);
        bt_fun.setOnClickListener(this);
        sys_info_fun.setOnClickListener(this);

        boolean enable = mSharedPreferences.getBoolean(Constants.VOICE_ENABLE,true);
        int volume = Integer.parseInt(mSharedPreferences.getString("volume_preference", "50"));
        acSeekBar.setProgress(volume);
        if ( !enable )
            imageVoice.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,R.mipmap.icon_mute));
        else
            imageVoice.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,R.mipmap.sound));
        acSeekBar.setEnabled( enable );

        imageVoice.setOnClickListener(view -> {
            boolean enable1 = mSharedPreferences.getBoolean(Constants.VOICE_ENABLE,true);
            if ( enable1 ) {
                imageVoice.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,R.mipmap.icon_mute));
            } else {
                imageVoice.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,R.mipmap.sound));
            }
            acSeekBar.setEnabled( !enable1 );
            mSharedPreferences.edit().putBoolean(Constants.VOICE_ENABLE,!enable1)
                    .apply();
        });
        acSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                Log.d( "X123","onProgressChanged.." + progress );
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Log.d( "X123","onStartTrackingTouch.." );
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Log.d( "X123","onStopTrackingTouch.." );
                mSharedPreferences.edit().putString("volume_preference",String.valueOf(seekBar.getProgress()))
                        .apply();
            }
        });
        EventBus.getDefault().register(this);
        initLocation();
        checkLocationPermission();
        new Thread(() -> Utils.getNetIp(MainActivity.this)).start();
        startService(new Intent(this, XService.class));
    }

    @Override
    public void onBackPressed() {
//        super.onBackPressed();
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.wifi_fun:
                Intent intent = new Intent();
                intent.setAction("android.net.wifi.PICK_WIFI_NETWORK");
                startActivity(intent);
                break;
            case R.id.dev_fun:
                startActivity(new Intent(this, DevActivity.class));
                break;
            case R.id.bt_fun:
                BlueToothFragment fragment = new BlueToothFragment();
                fragment.show(getSupportFragmentManager(), fragment.getClass().getSimpleName());
                break;
            case R.id.sys_info_fun:
                SysFragment fragment1 = new SysFragment();
                fragment1.show(getSupportFragmentManager(), fragment1.getClass().getSimpleName());
                break;
        }
    }


    /**
     * 判断是否有SDK需要的权限，没有的话动态获取
     */
    private void initPermission() {
        Utils.setIsGetBpData(this, false);
        RxPermissions permissions = new RxPermissions(this);
        permissions.setLogging(true);
        permissions.request(Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(aBoolean -> {
                    if (aBoolean) {
                        //权限已经都通过了，可以将程序继续打开了
                        OMRONLib omronlib = OMRONLib.getInstance();
                        String deviceId = mSharedPreferences.getString(Constants.deviceId, null);
                        if (null == deviceId) {
                            DeviceType deviceType = Constants.mDeviceType;
                            omronlib.StopScan();
                            omronlib.bindDevice(MainActivity.this, deviceType, myOmronBleCallBack);
                        } else
                            Utils.setIsGetBpData(MainActivity.this, true);
                    } else {
                        Toast.makeText(MainActivity.this, "欧姆龙初始化获取权限失败", Toast.LENGTH_SHORT).show();
                    }
                });
    }

    /*********************************欧姆龙*************************************/
    private OMRONLib.OmronBleCallBack myOmronBleCallBack = new OMRONLib.OmronBleCallBack() {
        @Override
        public void onFailure(OMRONBLEErrMsg omronbleErrMsg) {
            Utils.setIsGetBpData(MainActivity.this, true);
            runOnUiThread(() ->
                    Toast.makeText(MainActivity.this,
                            null != omronbleErrMsg ? omronbleErrMsg.getErrMsg() : "设备绑定失败",
                            Toast.LENGTH_SHORT).show());

        }

        @Override
        public void onBindComplete(String deviceName, String deviceId, String mac) {
            Utils.setIsGetBpData(MainActivity.this, true);
            runOnUiThread(() -> {
                Toast.makeText(MainActivity.this, "设备绑定成功", Toast.LENGTH_SHORT).show();
                /* BLEsmart_00000116B0495F045A76,HEM-9200T20180400128L */
                SharedPreferences mSharedPreferences = PreferenceManager
                        .getDefaultSharedPreferences(MainActivity.this);
                mSharedPreferences.edit()
                        .putString(Constants.deviceId, deviceId)
                        .putString(Constants.deviceName, deviceName)
                        .putString(Constants.deviceMac, mac)
                        .apply();
            });

        }

        @Override
        public void onDataReadComplete(List<BPData> list) {

        }
    };

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(BPData event) {
//        if ( event != null )
//            tvNewest.setText(
//                    "高压：" + event.getSystolic() +
//                    "；低压：" + event.getDiastolic() +
//                    "；脉搏：" + event.getPulse() +
//                    "；\n时间：" + sdf.format(event.getMeasureTime()) );
    }

    /************************************************************************/

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread1(TLBean event) {
        Log.d(TAG, "want to locate...");
        if (event != null)
            checkLocationPermission();
    }

    /*********************************华为定位*******http://tangfan.top/api/Az/Bp****************************/

    LocationCallback mLocationCallback;
    LocationRequest mLocationRequest;
    private FusedLocationProviderClient mFusedLocationProviderClient;
    private SettingsClient mSettingsClient;

    private void checkLocationPermission() {
        RxPermissions permissions = new RxPermissions(this);
        permissions.setLogging(true);
        Observable<Boolean> observable;
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P)
            observable = permissions.request(Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION);
        else
            observable = permissions.request(Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    "android.permission.ACCESS_BACKGROUND_LOCATION");
        observable.subscribe(aBoolean -> {
            if (aBoolean)
                requestLocationUpdatesWithCallback();
            else
                Toast.makeText(MainActivity.this, "没有定位权限。", Toast.LENGTH_SHORT).show();
        });
    }


    private void initLocation() {
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        mSettingsClient = LocationServices.getSettingsClient(this);
        mLocationRequest = new LocationRequest();
        // Sets the interval for location update (unit: Millisecond)
        mLocationRequest.setInterval(5000);
        // Sets the priority
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        if (null == mLocationCallback) {
            mLocationCallback = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    if (locationResult != null) {
                        List<Location> locations = locationResult.getLocations();
                        if (!locations.isEmpty()) {
                            for (Location location : locations) {
                                Log.i(TAG,
                                        "onLocationResult location[Longitude,Latitude,Accuracy]:" + location.getLongitude()
                                                + "," + location.getLatitude() + "," + location.getAccuracy());
                                mSharedPreferences.edit()
                                        .putFloat("Latitude", (float) location.getLatitude())
                                        .putFloat("Longitude", (float) location.getLongitude())
                                        .apply();

                                removeLocationUpdatesWithCallback();
                            }
                        }
                    }
                }

                @Override
                public void onLocationAvailability(LocationAvailability locationAvailability) {
                    if (locationAvailability != null) {
                        boolean flag = locationAvailability.isLocationAvailable();
                        Log.i(TAG, "onLocationAvailability isLocationAvailable:" + flag);
                    }
                }
            };
        }
    }

    private void requestLocationUpdatesWithCallback() {
        try {
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
            builder.addLocationRequest(mLocationRequest);
            LocationSettingsRequest locationSettingsRequest = builder.build();
            // Before requesting location update, invoke checkLocationSettings to check device settings.
            Task<LocationSettingsResponse> locationSettingsResponseTask = mSettingsClient.checkLocationSettings(locationSettingsRequest);
            locationSettingsResponseTask.addOnSuccessListener(locationSettingsResponse -> {
                Log.i(TAG, "check location settings success");
                mFusedLocationProviderClient
                        .requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
                        .addOnSuccessListener(aVoid -> Log.i(TAG, "requestLocationUpdatesWithCallback onSuccess"))
                        .addOnFailureListener(e -> Log.e(TAG,
                                "requestLocationUpdatesWithCallback onFailure:" + e.getMessage()));
            })
                    .addOnFailureListener(e -> {
                        Log.e(TAG, "checkLocationSetting onFailure:" + e.getMessage());
                        int statusCode = ((ApiException) e).getStatusCode();
                        switch (statusCode) {
                            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                try {
                                    //When the startResolutionForResult is invoked, a dialog box is displayed, asking you to open the corresponding permission.
                                    ResolvableApiException rae = (ResolvableApiException) e;
                                    rae.startResolutionForResult(MainActivity.this, 0);
                                } catch (IntentSender.SendIntentException sie) {
                                    Log.e(TAG, "PendingIntent unable to execute request.");
                                }
                                break;
                        }
                    });
        } catch (Exception e) {
            Log.e(TAG, "requestLocationUpdatesWithCallback exception:" + e.getMessage());
        }
    }

    private void removeLocationUpdatesWithCallback() {
        try {
            Task<Void> voidTask = mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback);
            voidTask.addOnSuccessListener(aVoid -> Log.i(TAG, "removeLocationUpdatesWithCallback onSuccess"))
                    .addOnFailureListener(e -> Log.e(TAG, "removeLocationUpdatesWithCallback onFailure:" + e.getMessage()));
        } catch (Exception e) {
            Log.e(TAG, "removeLocationUpdatesWithCallback exception:" + e.getMessage());
        }
    }

    /************************************************************************/

    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }
}
